﻿
namespace predic.Web.Host.Services
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.ComponentModel.DataAnnotations;
    using System.Data;
    using System.Data.Linq.SqlClient;
    using System.Linq;
    using System.ServiceModel.DomainServices.EntityFramework;
    using System.ServiceModel.DomainServices.Hosting;
    using System.ServiceModel.DomainServices.Server;
    using predic.Web.Host.Model;
    using System.Data.Objects.SqlClient;
    using System.Linq.Expressions;
    using System.Data.Objects.DataClasses;
    using System.Runtime.Serialization;
    using System.Threading.Tasks;

    // Implements application logic using the predicEntities1 context.
    // TODO: Add your application logic to these methods or in additional methods.
    // TODO: Wire up authentication (Windows/ASP.NET Forms) and uncomment the following to disable anonymous access
    // Also consider adding roles to restrict access as appropriate.
    // [RequiresAuthentication]
    [EnableClientAccess()]
    public class PredicService : LinqToEntitiesDomainService<predicEntities1>
    {

        //Main Filter
        public IQueryable<ViewStudy> GetStudiesView()
        {
            return this.ObjectContext.ViewStudies.OrderBy(item => item.IDStudy);
        }
        public IQueryable<ViewStudy> GetStudiesViewWithFilter(int preacherID, string title, string subtitle)
        {

            IQueryable<ViewStudy> query = null;

            if (preacherID > 0)
            {
                query = from item in this.ObjectContext.ViewStudies
                        where
                              item.IDPreacher == preacherID
                              && item.Title.Contains(title)
                              && item.Subtitle.Contains(subtitle)

                        orderby item.IDStudy ascending
                        select item;
            }
            else
            {
                query = from item in this.ObjectContext.ViewStudies
                        where
                              item.Title.Contains(title)
                              && item.Subtitle.Contains(subtitle)

                        orderby item.IDStudy ascending
                        select item;
            }

            return query;
        }

        public ViewStudy GetStudyViewByDetailID(int detailID)
        {
            return this.ObjectContext.ViewStudies
                .Where(item => item.IDDetail == detailID)
                .OrderBy(item => item.IDStudy)
                .FirstOrDefault();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="viewStudy"></param>
        public void UpdateViewStudy(ViewStudy viewStudy)
        {
            
            // update study
            Study study = this.ObjectContext.Studies.Where(item => item.ID == viewStudy.IDStudy).FirstOrDefault();
            if (study != null)
            {
                study.Title = viewStudy.Title;
                study.Subtitle = viewStudy.Subtitle;
                study.Tematica = viewStudy.Tematica;
                study.Text = viewStudy.Text;
                study.Subiect = viewStudy.Subiect;
            }

            this.ObjectContext.SaveChanges();
        }


        public void PreacherStudy(string preacherName, string title, string subtitle, string text, string tematica, string subiect)
        {
            // match preacher name
            string[] pearcherNameTokens = preacherName.Split(' ');
            string firstName = string.Empty;
            string lastName = string.Empty;

            Preacher preacher = null;

            if (pearcherNameTokens.Count() >= 2)
            {
                firstName = pearcherNameTokens[0];
                lastName = pearcherNameTokens[1];

                preacher = GetPreacherByName(firstName, lastName);

                if (preacher == null)
                {
                    preacher = GetPreacherByName(lastName, firstName);
                }
            }
            else
            {
                preacher = GetPreacherByName(preacherName, string.Empty);

                if (preacher == null)
                {
                    preacher = GetPreacherByName(string.Empty, preacherName);
                }
            }

            if (preacher == null)
            {
                preacher = new Preacher();
                preacher.FirstName = firstName;
                preacher.LastName = lastName;

                this.ObjectContext.Preachers.AddObject(preacher);
            }


            Study study = new Study();
            study.Title = title;
            study.Subtitle = subtitle;
            study.Text = text;
            study.Tematica = tematica;
            study.Subiect = subiect;
            study.Preacher = preacher;

            this.ObjectContext.SaveChanges();
        }

        #region Details

        public IQueryable<Detail> GetDetails()
        {
            return this.ObjectContext.Details;
        }
        public Detail GetDetailByIDStudy(int idStudy)
        {
            return this.ObjectContext.Details
                .Where(item => item.IDStudy == idStudy)
                .FirstOrDefault();
        }

        public void InsertDetail(Detail detail)
        {
            if ((detail.EntityState != EntityState.Detached))
            {
                this.ObjectContext.ObjectStateManager.ChangeObjectState(detail, EntityState.Added);
            }
            else
            {
                this.ObjectContext.Details.AddObject(detail);
            }
        }
        public void UpdateDetail(Detail currentDetail)
        {
            this.ObjectContext.Details.AttachAsModified(currentDetail, this.ChangeSet.GetOriginal(currentDetail));
        }
        public void DeleteDetail(Detail detail)
        {
            if ((detail.EntityState == EntityState.Detached))
            {
                this.ObjectContext.Details.Attach(detail);
            }
            this.ObjectContext.Details.DeleteObject(detail);
        }

        #endregion

        #region Preacher

        public IQueryable<Preacher> GetPreachers()
        {
            return this.ObjectContext.Preachers;
        }
        public IQueryable<Preacher> GetPreachersByID(int id)
        {
            return this.ObjectContext.Preachers.Where(p => p.ID == id);
        }

        private Preacher GetPreacherByName(string firstName, string lastName)
        {
            return this.ObjectContext.Preachers
                    .Where(item => item.FirstName.Equals(firstName, StringComparison.InvariantCultureIgnoreCase) && item.LastName.Equals(lastName, StringComparison.InvariantCultureIgnoreCase))
                    .FirstOrDefault();
        }

        public void InsertPreacher(Preacher preacher)
        {
            if ((preacher.EntityState != EntityState.Detached))
            {
                this.ObjectContext.ObjectStateManager.ChangeObjectState(preacher, EntityState.Added);
            }
            else
            {
                this.ObjectContext.Preachers.AddObject(preacher);
            }
        }
        public void UpdatePreacher(Preacher currentPreacher)
        {
            this.ObjectContext.Preachers.AttachAsModified(currentPreacher, this.ChangeSet.GetOriginal(currentPreacher));
        }
        public void DeletePreacher(Preacher preacher)
        {
            if ((preacher.EntityState == EntityState.Detached))
            {
                this.ObjectContext.Preachers.Attach(preacher);
            }
            this.ObjectContext.Preachers.DeleteObject(preacher);
        }

        #endregion

        #region Studies

        public IQueryable<Study> GetStudies()
        {
            return this.ObjectContext.Studies;
        }
        public IQueryable<Study> GetStudiesByPreacher(int idPreacher)
        {
            return this.ObjectContext.Studies.Where(item => item.IDPreacher == idPreacher);
        }
        public IQueryable<Study> GetStudiesByCriteria(int idPreacher, string title, string subtitle)
        {
            IQueryable<Study> result = this.ObjectContext.Studies.Where(s => s.IDPreacher == idPreacher);

            if (!string.IsNullOrEmpty(title))
            {
                result = result.Where(s => s.Title.ToLower().Contains(title.ToLower()));
            }

            if (!string.IsNullOrEmpty(subtitle))
            {
                result = result.Where(s => s.Subtitle.ToLower().Contains(subtitle.ToLower()));
            }

            return result;
        }

        public IQueryable<CustomStringTransport> GetDistinctTitlesByPreacher(int idPreacher)
        {
            if (idPreacher > 0)
            {

                return this.ObjectContext.Studies.Where(s => s.IDPreacher == idPreacher)
                    .Select(s => new CustomStringTransport { CustomValue = s.Title })
                    .OrderBy(s => s.CustomValue)
                    .Distinct();
            }

            return this.ObjectContext.Studies
                   .Select(s => new CustomStringTransport { CustomValue = s.Title })
                   .OrderBy(s => s.CustomValue)
                   .Distinct();
        }
        public IQueryable<CustomStringTransport> GetDistinctSubtitlesByPreacher(int idPreacher)
        {
            if (idPreacher > 0)
            {
                return this.ObjectContext.Studies
                    .Where(s => s.IDPreacher == idPreacher)
                    .Select(s => new CustomStringTransport { CustomValue = s.Subtitle })
                    .OrderBy(s => s.CustomValue)
                    .Distinct();
            }

            return this.ObjectContext.Studies
                    .Select(s => new CustomStringTransport { CustomValue = s.Subtitle })
                    .OrderBy(s => s.CustomValue)
                    .Distinct();
        }

        public IQueryable<CustomStringTransport> GetDistinctSubtitlesByPreacherAndTitle(int idPreacher, string title)
        {
            if (idPreacher > 0 && !string.IsNullOrEmpty(title))
            {
                return this.ObjectContext.Studies
                    .Where(s => s.IDPreacher == idPreacher && s.Title == title)
                    .Select(s => new CustomStringTransport { CustomValue = s.Subtitle })
                    .Distinct();
            }

            else if (idPreacher > 0 && string.IsNullOrEmpty(title))
            {
                return this.ObjectContext.Studies
                    .Where(s => s.IDPreacher == idPreacher)
                    .Select(s => new CustomStringTransport { CustomValue = s.Subtitle })
                    .Distinct();
            }

            else if (idPreacher < 0 && !string.IsNullOrEmpty(title))
            {
                return this.ObjectContext.Studies
                    .Where(s => s.Title == title)
                    .Select(s => new CustomStringTransport { CustomValue = s.Subtitle })
                    .Distinct();
            }

            else if (idPreacher < 0 && string.IsNullOrEmpty(title))
            {
                return this.ObjectContext.Studies
                    .Select(s => new CustomStringTransport { CustomValue = s.Subtitle })
                    .Distinct();
            }

            return null;
        }

        public void InsertStudy(Study study)
        {
            if ((study.EntityState != EntityState.Detached))
            {
                this.ObjectContext.ObjectStateManager.ChangeObjectState(study, EntityState.Added);
            }
            else
            {
                this.ObjectContext.Studies.AddObject(study);
            }
        }
        public void UpdateStudy(Study currentStudy)
        {
            this.ObjectContext.Studies.AttachAsModified(currentStudy, this.ChangeSet.GetOriginal(currentStudy));
        }
        public void DeleteStudy(Study study)
        {
            if ((study.EntityState == EntityState.Detached))
            {
                this.ObjectContext.Studies.Attach(study);
            }
            this.ObjectContext.Studies.DeleteObject(study);
        }

        #endregion
    }


}


